﻿using Common.Api.Client;
using Common.Api.Dtos;
using Cyss.Core.Helper;
using Cyss.TaskManager.Models;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Cyss.TaskManager.Infrastructure
{




    public class TaskThread
    {
        /// <summary>
        /// 任务配置
        /// </summary>
        public TaskConfigModel Config { set; get; }

        #region 构造函数
        public TaskThread()
        {

        }

        #endregion

        #region 成员

        #region 私有成员

        /// <summary>
        /// 记录执行次数
        /// </summary>
        public long Counter { set; get; }

        /// <summary>
        /// 是否正在释放
        /// </summary>
        private bool _disposed;

        /// <summary>
        /// 是否关闭
        /// </summary>
        private bool RunOnlyOnce = false;

        /// <summary>
        /// 显示顺序
        /// </summary>
        public int DisplayOrder { set; get; }
        #endregion

        #region public

        /// <summary>
        /// 日志最大显示多少条，默认200条
        /// </summary>
        public int LogMaxCount { set; get; }

        /// <summary>
        /// 任务Id
        /// </summary>
        public int Id { set; get; }

        /// <summary>
        /// 任务名称
        /// </summary>
        public string ServiceName { set; get; }


        /// <summary>
        ///任务
        /// </summary>
        public Type TaskType { set; get; }


        public UrlService UrlService { set; get; }

        /// <summary>
        /// 上下文
        /// </summary>
        public object Context { set; get; }

        #region 间隔时间秒
        public int Interval { set; get; }
        private int _Interval { get { return Interval * 1000; } }

        #endregion

        #region 开始执行时间
        protected DateTime _StartDatetime;
        /// <summary>
        /// 开始执行时间
        /// </summary>
        public virtual DateTime StartDatetime
        {
            set
            {
                if (_StartDatetime != value)
                {
                    _StartDatetime = value;
                }
            }
            get { return _StartDatetime; }
        }




        #endregion

        #region 结束执行时间
        protected DateTime _EndDateTime;
        /// <summary>
        /// 结束执行时间
        /// </summary>
        public virtual DateTime EndDateTime
        {
            set
            {
                if (_EndDateTime != value)
                {
                    _EndDateTime = value;
                }

            }
            get { return _EndDateTime; }
        }




        #endregion

        #region 状态
        protected bool _State;
        public virtual bool State
        {
            set
            {
                if (_State != value)
                {
                    _State = value;
                }

            }
            get { return _State; }
        }

        #endregion

        #region 是否正在执行任务

        protected bool _IsRuning;
        public virtual bool IsRuning
        {
            set
            {
                if (_State != value)
                {
                    _State = value;
                }

            }
            get { return _State; }
        }


        #endregion


        #region 是否在关闭中
        private bool _colseing = false;
        /// <summary>
        /// 是否还在关闭中
        /// </summary>
        public bool Colseing { get { return _colseing; } }

        #endregion

        #endregion

        #endregion

        #region 私有方法

        /// <summary>
        /// 
        /// </summary>
        private async Task Run()
        {
            try
            {
                Counter++;
                bool IsSuccess = false;
                if (this.UrlService != null)
                {
                    IsSuccess = await this.UrlService.Start(Context);
                }
                else
                {
                    var instance = Activator.CreateInstance(TaskType) as IService;
                    IsSuccess = await instance.Start(Context);
                    instance = null;
                }
                if (IsSuccess == false && Config.FailNotCounted)
                {
                    Counter--;
                }

            }
            catch (Exception ex)
            {
                LoggingManager.Insert(new TaskLogging { TaskId = this.Id, Content = ex.Message, CreateTime = DateTime.Now, Type = "Exception" });
                LogHelper.WriteTextLog(ex.ToString(), "Run-Exception", "TaskThread");
            }

        }

        private async void UpdateTask()
        {
            var operateResult = await CommonClientFactory.Task.GetTaskById(this.Id);
            if (operateResult.IsSuccess)
            {
                operateResult.Data.IsRunning = this.IsRuning;
                operateResult.Data.Count = this.Counter;
                operateResult.Data.LastStartTime = this.StartDatetime;
                operateResult.Data.LaseEndTime = this.EndDateTime;
                await CommonClientFactory.Task.EditTask(operateResult.Data);
            }
        }
        public async void ExecuteAsync()
        {
            if (RunOnlyOnce)
            {
                Dispose();
                return;
            }

            IsRuning = true;
            StartDatetime = DateTime.Now;
            EndDateTime = DateTime.MinValue;
            UpdateTask();
            await Run();
            EndDateTime = DateTime.Now;
            IsRuning = false;
            UpdateTask();
            if (RunOnlyOnce)
            {
                Dispose();
            }
        }
        // <summary>
        ///     Disposes the instance
        /// </summary>
        private void Dispose()
        {
            if (!_disposed)
            {
                lock (this)
                {
                    _disposed = true;
                }
            }
            _colseing = false;
            State = false;
        }

        #endregion
    }
}
